package com.toomoss.USB2XXX;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;

import java.util.Arrays;
import java.util.List;

public interface USB2SENT extends Library {
	USB2SENT INSTANCE  = (USB2SENT)Native.loadLibrary("USB2XXX",USB2SENT.class);
	//定义函数返回错误代码
	public static int SENT_SUCCESS             =(0) ;  ///<函数执行成功
	public static int SENT_ERR_NOT_SUPPORT     =(-1);  ///<适配器不支持该函数
	public static int SENT_ERR_USB_WRITE_FAIL  =(-2) ; ///<USB写数据失败
	public static int SENT_ERR_USB_READ_FAIL   =(-3);  ///<USB读数据失败
	public static int SENT_ERR_CMD_FAIL        =(-4) ; ///<命令执行失败
	public static int SENT_ERR_PARAMETER       =(-7);  ///<函数参数传入有误
	public static int SENT_ERR_MSG_TYPE        =(-8) ; ///<当前函数不支持该消息类型
	//SENT主从模式
	public static byte SENT_MASTER    = 1; ///<主机模式，用于模拟主节点发送数据
	public static byte SENT_SLAVE     = 0; ///<从机模式，用于监控SENT主机发送出来的数据
	//SENT消息类型
	public static byte SENT_MSGTYPE_ERROR         = 0; ///<错误帧，比如CRC错误，数据不完整等
	public static byte SENT_MSGTYPE_FAST          = 1; ///<快速通道数据,数据存放在Data[0]~Data[7]里面，Status的高4位代表数据有效半字节数
	public static byte SENT_MSGTYPE_SLOW_SHORT    = 2; ///<慢速通道，简短型串行信息,Data[0]为ID,Data[1]为数据
	public static byte SENT_MSGTYPE_SLOW_ENH1     = 3; ///<慢速通道，增强型串行信息,12位数据+8位ID,Data[0]为ID，Data[1]为高4位数据,Data[2]为低8位数据
	public static byte SENT_MSGTYPE_SLOW_ENH2     = 4; ///<慢速通道，增强型串行信息,16位数据+4位ID,Data[0]为ID，Data[1]为高8位数据,Data[2]为低8位数据
	//SENT总线空闲电平
	public static byte SENT_IDLE_HIGH    = 1; ///<总线空闲时为高电平，数据输出低电平脉冲
	public static byte SENT_IDLE_LOW     = 0; ///<总线空闲时为低电平，数据输出高电平脉冲
	//SENT_CONFIG
	public class SENT_CONFIG  extends Structure {
		public static class ByReference extends USB2SENT.SENT_CONFIG implements Structure.ByReference {}
		public static class ByValue extends USB2SENT.SENT_CONFIG implements Structure.ByValue {}

		@Override
		protected List getFieldOrder() {
			// TODO Auto-generated method stub
			return Arrays.asList(new String[]{"TicksTimeUs","MasterMode","LowTicks","PausePulseTicks","NibbleNum","IdleLevel"});
		}
		//SENT初始化结构定义
		public byte   TicksTimeUs;    ///<Ticks时间，单位为us，一般为3
		public byte   MasterMode;     ///<0-从机模式，用于监控SENT总线数据，1-主机模式，用于发送SENT总线数据
		public byte   LowTicks;       ///<低电平输出Ticks数，低电平输出时间=TicksTimeUs*LowTicks，推荐设置为5
		public byte   PausePulseTicks;///<暂停脉冲数，0-不输出，1~64对应12Ticks~768Ticks
		public byte   NibbleNum;      ///<快速通道半字节数，不包含CRC，从机模式若是0则自动匹配，主机模式Status高4位代表要发送的有效半字节数
		public byte   IdleLevel;      ///<总线空闲状态，0-空闲低电平，1-空闲高电平
	}
	//SENT_MSG
	public class SENT_MSG  extends Structure {
		public static class ByReference extends USB2SENT.SENT_CONFIG implements Structure.ByReference {}
		public static class ByValue extends USB2SENT.SENT_MSG implements Structure.ByValue {}

		@Override
		protected List getFieldOrder() {
			// TODO Auto-generated method stub
			return Arrays.asList(new String[]{"Timestamp","TimestampHigh","Status","Data","crc","MsgType"});
		}
		//SENT初始化结构定义
		public int   Timestamp;    			///<接收到信息帧时的时间标识，从SENT控制器初始化开始计时，单位为100us。发送数据时为帧间隔时间，单位为ms
		public byte   TimestampHigh;     	///<接收数据时为时间戳高位,发送帧时为该帧发送次数
		public byte   Status;       		///<高4位代表Data有效字节数，低4位代表Status
		public byte[]   Data=new byte[8];	///<根据帧类型存储不同的数据
		public byte   crc;      			///<MsgType若为增强型串行信息，则是6bit有效CRC，其他的为4bit有效CRC，bit7-当前帧为错误帧
		public byte   MsgType;      		///<帧类型，具体可以参考帧类型定义
	}
	/**
	 * @brief 初始化配置SENT总线，必须调用，否则无法正常工作
	 * @param DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param Channel SENT通道号，0-SENT1，1-SENT2，2-SENT3，3-SENT4，SENT总线在硬件上是跟LIN总线共用的
	 * @param[in] pConfig 初始化结构体，可以参考 @ref SENT初始化结构定义 查看参数详情
	 * @return 函数执行状态
	 * @retval =0 函数执行成功
	 * @retval !=0 函数执行失败
	 */
	int SENT_Init(int DevHandle,byte Channel, SENT_CONFIG pConfig);

	/**
	 * @brief  主机模式下手动发送SENT消息
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  Channel SENT通道号，0-SENT1，1-SENT2，2-SENT3，3-SENT4，SENT总线在硬件上是跟LIN总线共用的
	 * @param[in]  pSentMsg SENT消息帧指针
	 * @param  MsgNum 发送的SENT消息帧数，不能大于64帧
	 * @return 函数执行状态
	 * @retval =0 函数执行成功
	 * @retval !=0 函数执行失败
	 */
	int SENT_SendMsg(int DevHandle, byte Channel, SENT_MSG pSentMsg, int MsgNum);

	/**
	 * @brief  设置并启动SENT快速通道帧发送列表
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  Channel SENT通道号，0-SENT1，1-SENT2，2-SENT3，3-SENT4，SENT总线在硬件上是跟LIN总线共用的
	 * @param  pSentMsg SENT快速通道消息帧指针
	 * @param  MsgNum 发送的SENT消息帧数，不能大于64帧
	 * @param  SendTimes 列表循环发送次数，若设置为0xFFFFFFFF则一直循环发送列表，直到调用 @ref SENT_StopFastMsgTable 函数为止
	 * @return 函数执行状态
	 * @retval =0 函数执行成功
	 * @retval !=0 函数执行失败
	 */
	int SENT_StartFastMsgTable(int DevHandle, byte Channel, SENT_MSG pSentMsg,  int MsgNum, int SendTimes);

	/**
	 * @brief  停止正在发送的SENT帧列表
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  Channel SENT通道号，0-SENT1，1-SENT2，2-SENT3，3-SENT4，SENT总线在硬件上是跟LIN总线共用的
	 * @return 函数执行状态
	 * @retval =0 函数执行成功
	 * @retval !=0 函数执行失败
	 */
	int SENT_StopFastMsgTable(int DevHandle, byte Channel);

	/**
	 * @brief  设置并启动SENT慢速通道帧发送列表，调用该函数后数据不会立即发送，它是在发送快速数据的时候才通过Status域发送，所以需要发送慢速通道帧数据，需要同时启动快速帧发送列表
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  Channel SENT通道号，0-SENT1，1-SENT2，2-SENT3，3-SENT4，SENT总线在硬件上是跟LIN总线共用的
	 * @param  pSentMsg SENT慢速通道消息帧指针
	 * @param  MsgNum 发送的SENT消息帧数，不能大于64帧
	 * @param  SendTimes 列表循环发送次数，若设置为0xFFFFFFFF则一直循环发送列表，直到调用 @ref SENT_StopSlowMsgTable 函数为止
	 * @return
	 */
	int SENT_StartSlowMsgTable(int DevHandle, byte Channel, SENT_MSG pSentMsg, int MsgNum, int SendTimes);

	/**
	 * @brief  停止正在发送的SENT帧列表
	 * @param  DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param  Channel SENT通道号，0-SENT1，1-SENT2，2-SENT3，3-SENT4，SENT总线在硬件上是跟LIN总线共用的
	 * @return 函数执行状态
	 * @retval =0 函数执行成功
	 * @retval !=0 函数执行失败
	 */
	int SENT_StopSlowMsgTable(int DevHandle, byte Channel);

	/**
	 * @brief 主机模式获取已发成功发送出去的帧，从机模式获取监控到的帧
	 * @param DevHandle 设备号，通过调用 @ref USB_ScanDevice 获取
	 * @param Channel SENT通道号，0-SENT1，1-SENT2，2-SENT3，3-SENT4，SENT总线在硬件上是跟LIN总线共用的
	 * @param pSentMsg 存储SENT帧缓冲区指针，该缓冲区不能小于64，否则可能会出现缓冲区溢出导致程序异常闪退
	 * @return 成功获取到的SENT消息帧数
	 * @retval <0 函数执行失败
	 */
	int SENT_GetMsg(int DevHandle, byte Channel, SENT_MSG pSentMsg);

}
